www.gusucode.com > VC++ 曲线的绘制-源码程序 > VC++ 曲线的绘制-源码程序/code/LinePlotTestDlg.cpp

    //Download by http://www.NewXing.com
// LinePlotTestDlg.cpp : implementation file
//

#include "stdafx.h"
#include "LinePlotTest.h"
#include "LinePlotTestDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}
/////////////////////////////////////////////////////////////////////////////

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}
/////////////////////////////////////////////////////////////////////////////

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLinePlotTestDlg dialog

CLinePlotTestDlg::CLinePlotTestDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CLinePlotTestDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CLinePlotTestDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
/////////////////////////////////////////////////////////////////////////////

void CLinePlotTestDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CLinePlotTestDlg)
	DDX_Control(pDX, ID_CMB_STYLE, m_cmbStyle);
	DDX_Control(pDX, ID_LST_RECEIVED, m_lstReceived);
	//}}AFX_DATA_MAP
}
/////////////////////////////////////////////////////////////////////////////

BEGIN_MESSAGE_MAP(CLinePlotTestDlg, CDialog)
	//{{AFX_MSG_MAP(CLinePlotTestDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_SIZE()
	ON_BN_CLICKED(ID_BTN_CURR_COLOR, OnBtnCurrColor)
	ON_BN_CLICKED(ID_BTN_CURR_UPDATE, OnBtnCurrUpdate)
	ON_BN_CLICKED(ID_BTN_CURR_REMOVE, OnBtnCurrRemove)
	ON_BN_CLICKED(ID_BTN_CLEAR, OnBtnClear)
	ON_CBN_CLOSEUP(ID_CMB_STYLE, OnCloseupCmbStyle)
  ON_NOTIFY(NM_PLOT_SEL_CHANGE, ID_CTRL_LINE_PLOT, OnPlotSelChange)
  ON_NOTIFY(NM_PLOT_LIMITS_CHANGE, ID_CTRL_LINE_PLOT, OnPlotLimitsChange)
  ON_NOTIFY(NM_PLOT_MOUSE_MOVE, ID_CTRL_LINE_PLOT, OnPlotMouseMove)
	ON_BN_CLICKED(ID_BTN_LOAD_FROM_FILE, OnBtnLoadFromFile)
	ON_BN_CLICKED(ID_BTN_PRINT, OnBtnPrint)
	ON_BN_CLICKED(ID_BTN_SAVE_TO_FILE, OnBtnSaveToFile)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLinePlotTestDlg message handlers
/////////////////////////////////////////////////////////////////////////////

BOOL CLinePlotTestDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here

  CRect rcClient;
  GetWindowRect(&rcClient);
  rcClient.bottom = rcClient.top + 300;
  rcClient.right = rcClient.left + 900;
  MoveWindow(&rcClient);

  //  create the line plot control.
  m_LinePlot.Create(CRect(0, 0, 1, 1), WS_CHILD | WS_VISIBLE, this, ID_CTRL_LINE_PLOT);

  //  size all controls correctly;
	SizeControls();

  UINT ii;

  //  add a plot to the control.
  FLOATPOINT pData2[101];
  srand((unsigned)time(NULL));
  for (ii=0; ii<101; ii++)
  {
    pData2[ii].x = (float)(ii);
    pData2[ii].y = (float)((rand() / (RAND_MAX / 20)) - 10.0f);
  }
  COLORREF crColor2 = RGB (0, 0, 255);
  m_LinePlot.Add("Blue Data", crColor2, CLinePlot::LpBar, pData2, 100);

  //  add a plot to the control.
  FLOATPOINT pData3[400];
  for (ii=0; ii<400; ii++)
  {
    pData3[ii].x = (float)(ii);
    pData3[ii].y = (float)(cos((float)(ii)/4.0f)*8);
  }
  COLORREF crColor3 = RGB (0, 128, 0);
  m_LinePlot.Add("Green Data", crColor3, CLinePlot::LpLine, pData3, 101);

  //  add a plot to the control.
  FLOATPOINT pData1[101];
  for (ii=0; ii<101; ii++)
  {
    pData1[ii].x = (float)(ii+1);
    pData1[ii].y = - (float)(ii % 10 + 1);
  }
  COLORREF crColor1 = RGB (255, 0, 0);
  m_LinePlot.Add("Red Data", crColor1, CLinePlot::LpLine, pData1, 101);

	return TRUE;  // return TRUE  unless you set the focus to a control
}
/////////////////////////////////////////////////////////////////////////////

void CLinePlotTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}
/////////////////////////////////////////////////////////////////////////////

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CLinePlotTestDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}
/////////////////////////////////////////////////////////////////////////////

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CLinePlotTestDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}
/////////////////////////////////////////////////////////////////////////////
    
void CLinePlotTestDlg::SizeControls()
{
  CRect rcClient;
  GetClientRect(&rcClient);
  rcClient.left += 200;

  if (m_LinePlot.m_hWnd!=NULL)
    m_LinePlot.MoveWindow(200, 0, rcClient.Width(), rcClient.Height());

  if (m_lstReceived.m_hWnd!=NULL)
  {
    CRect rcArea;
    m_lstReceived.GetWindowRect(&rcArea);
    ScreenToClient(&rcArea);
    rcArea.bottom = rcClient.bottom;
    m_lstReceived.MoveWindow(rcArea.left, rcArea.top, rcArea.Width(), rcArea.Height());
  }
}
/////////////////////////////////////////////////////////////////////////////

void CLinePlotTestDlg::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	
	SizeControls();	
}
/////////////////////////////////////////////////////////////////////////////

BOOL CLinePlotTestDlg::PreCreateWindow(CREATESTRUCT& cs) 
{
	// TODO: Add your specialized code here and/or call the base class
	//cs.style |= WS_CLIPCHILDREN;
	return CDialog::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////

void CLinePlotTestDlg::OnBtnCurrColor() 
{
  //  get the current plot index.
  int nIndex = m_LinePlot.Selected();

  if (nIndex<0 || nIndex>=m_LinePlot.Count())
    AfxMessageBox("There is no plot selected.");
  else
  {
    //  get the color.
    COLORREF crCurr = m_LinePlot.GetColor(nIndex);
    //  show the color dialog.
    CColorDialog dlgColor(crCurr, CC_FULLOPEN);

    if (dlgColor.DoModal()==IDOK)
    {
      //  update the current color.
      m_LinePlot.SetColor(nIndex, dlgColor.GetColor());
    }
  }
}
/////////////////////////////////////////////////////////////////////////////

void CLinePlotTestDlg::OnBtnCurrUpdate() 
{
  //  get the current plot index.
  int nIndex = m_LinePlot.Selected();

  if (nIndex<0 || nIndex>=m_LinePlot.Count())
    AfxMessageBox("There is no plot selected.");
  else
  {
    //  get the number of points (this must match for an update).
    UINT uiPointCount = m_LinePlot.GetPointCount(nIndex);
    //  is it valid?
    if (uiPointCount>0)
    {
      //  declare a new array which will be copied.
      FLOATPOINT *pData = new FLOATPOINT[uiPointCount];
      srand((unsigned)time(NULL));
      for (UINT ii=0; ii<uiPointCount; ii++)
      {
        pData[ii].x = (float)(ii);
        pData[ii].y = (float)(rand() * 20.0f / RAND_MAX) - 10.0f;
      }
      m_LinePlot.SetData(nIndex, pData);
      delete pData;
    }
  }
}
/////////////////////////////////////////////////////////////////////////////

void CLinePlotTestDlg::OnBtnCurrRemove() 
{
  //  get the current plot index.
  int nIndex = m_LinePlot.Selected();

  if (nIndex<0 || nIndex>=m_LinePlot.Count())
    AfxMessageBox("There is no plot selected.");
  else
  {
    if (m_LinePlot.Remove(nIndex)!=true)
    {
      AfxMessageBox("Could not remove current plot.");
    }
  }
}
/////////////////////////////////////////////////////////////////////////////

void CLinePlotTestDlg::OnPlotMouseMove(NMHDR* pNMHDR, LRESULT* pResult)
{
  //  add this message to the notification list.
  m_lstReceived.AddString(_T("NM_PLOT_MOUSE_MOVE"));
}
/////////////////////////////////////////////////////////////////////////////

void CLinePlotTestDlg::OnPlotLimitsChange(NMHDR* pNMHDR, LRESULT* pResult)
{
  //  add this message to the notification list.
  m_lstReceived.AddString(_T("NM_PLOT_LIMITS_CHANGE"));
}
/////////////////////////////////////////////////////////////////////////////

void CLinePlotTestDlg::OnPlotSelChange(NMHDR* pNMHDR, LRESULT* pResult)
{
  //  add this message to the notification list.
  m_lstReceived.AddString(_T("NM_PLOT_SEL_CHANGE"));

  //  get the current plot index.
  int nIndex = m_LinePlot.Selected();

  if (nIndex<0 || nIndex>=m_LinePlot.Count())
    ;  //AfxMessageBox("There is no plot selected.");
  else
  {
    //  change enum type to index.
    int nComboIndex = (int)(m_LinePlot.GetStyle(nIndex));

    if (nComboIndex>=0 && nComboIndex<m_cmbStyle.GetCount())
    {
      //  set the combo selection.
      m_cmbStyle.SetCurSel(nComboIndex);
    }
  }
}
/////////////////////////////////////////////////////////////////////////////

void CLinePlotTestDlg::OnCloseupCmbStyle() 
{
  //  get the current plot index.
  int nIndex = m_LinePlot.Selected();

  if (nIndex<0 || nIndex>=m_LinePlot.Count())
    AfxMessageBox("There is no plot selected.");
  else
  {
    int nComboIndex = m_cmbStyle.GetCurSel();

    if (nComboIndex>=0 && nComboIndex<m_cmbStyle.GetCount())
    {
      //  change to the enum type.
      CLinePlot::enumPlotStyle enumStyle = (CLinePlot::enumPlotStyle)(nComboIndex);
      //  set the plot type.
      m_LinePlot.SetStyle(nIndex, enumStyle);
    }
  }
}
/////////////////////////////////////////////////////////////////////////////

void CLinePlotTestDlg::OnBtnClear() 
{
	m_lstReceived.ResetContent();
}
/////////////////////////////////////////////////////////////////////////////

void CLinePlotTestDlg::OnBtnPrint() 
{
	m_LinePlot.Print();
}
/////////////////////////////////////////////////////////////////////////////

void CLinePlotTestDlg::OnBtnLoadFromFile() 
{
  CString szTitle = "Load Plot Data From....";
  CString szSelFilename = "TestPlot.txt";
  CString szDefExtension = "txt";

  long nFilterIndex = 0;
  long nNumFilters = 0;
  CString szFilter = "";
  // do for certain file types.
  szFilter += "Text File (*.txt)|*.txt|";
  nNumFilters++;
  szFilter += "|";

  //  create the dialog.
  CFileDialog dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter);

  //  set the title
  dlgFile.m_ofn.lpstrTitle = szTitle.GetBuffer(MAX_PATH);
  //  set the flags.
  dlgFile.m_ofn.Flags |= OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
  //  set the default filename.
  dlgFile.m_ofn.lpstrFile = szSelFilename.GetBuffer(MAX_PATH);
  //  set the default extension.
  dlgFile.m_ofn.lpstrDefExt = szDefExtension.GetBuffer(MAX_PATH);
  //  set the number of filters
  dlgFile.m_ofn.nMaxCustFilter = nNumFilters;
  //  set the default filter.
  dlgFile.m_ofn.nFilterIndex = 0;

  //  show the dialog.
  if (dlgFile.DoModal()==IDOK)
  {
    //  release the buffer used for the filename.
    szSelFilename.ReleaseBuffer();

    //  pull out the name minus the extension.
    CString szName = szSelFilename;
    int nPos = szSelFilename.ReverseFind('.');
    if (nPos>=0)
      szName = szSelFilename.Left(nPos);
    nPos = szName.ReverseFind('\\');
    if (nPos>=0)
      szName = szName.Right(szName.GetLength() - nPos - 1);

    //  get a random color.
    srand((unsigned)time(NULL));
    BYTE yRed = (BYTE)(rand() / (RAND_MAX / 256) + 1);
    BYTE yGreen = (BYTE)(rand() / (RAND_MAX / 256) + 1);
    BYTE yBlue = (BYTE)(rand() / (RAND_MAX / 256) + 1);
    COLORREF crPlot = RGB(yRed, yGreen, yBlue);

    FILE *fPlot;
    if ((fPlot = fopen(szSelFilename, "r"))!=NULL)
    {
      //  get some temp storage.
      std::vector<FLOATPOINT> vecData;
      FLOATPOINT ptTemp = {0.0f, 0.0f};
      int nErr = 0;
      while (!feof(fPlot))
      {
        nErr = fscanf(fPlot, "%f\t%f\n",&(ptTemp.x), &(ptTemp.y));
        if (nErr==EOF)
          break;
        else
        {
          vecData.push_back(ptTemp);
        }
      }
      fclose(fPlot);
      //  add to the plot
      m_LinePlot.Add(szName, crPlot, CLinePlot::LpLine, &vecData);
    }
  }
	
}
/////////////////////////////////////////////////////////////////////////////

void CLinePlotTestDlg::OnBtnSaveToFile() 
{
  //  which plot is the current one?
  int nIndex = m_LinePlot.Selected();
  if (nIndex < 0)
    AfxMessageBox("No plot selected - select one and try again.");
  else
  {
    //  get  a pointer to the data.
    FLOATPOINT *pptData = m_LinePlot.GetData(nIndex);
    //  get the number of points.
    UINT uiPointCount = m_LinePlot.GetPointCount(nIndex);
    //  get the name of the plot.
    CString szName = m_LinePlot.GetName(nIndex);
    if (pptData == NULL || uiPointCount == 0)
      AfxMessageBox("Selected plot has no data - try another.");
    else
    {
      CString szTitle = "Save Plot Data To....";
      CString szSelFilename = szName + ".txt";
      CString szDefExtension = "txt";

      long nFilterIndex = 0;
      long nNumFilters = 0;
      CString szFilter = "";
      // do for certain file types.
      szFilter += "Text File (*.txt)|*.txt|";
      nNumFilters++;
      szFilter += "|";

      //  create the dialog.
      CFileDialog dlgFile(FALSE, NULL, NULL, 0, szFilter);

      //  set the title
      dlgFile.m_ofn.lpstrTitle = szTitle.GetBuffer(MAX_PATH);
      //  set the flags.
      dlgFile.m_ofn.Flags |= OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
      //  set the default filename.
      dlgFile.m_ofn.lpstrFile = szSelFilename.GetBuffer(MAX_PATH);
      //  set the default extension.
      dlgFile.m_ofn.lpstrDefExt = szDefExtension.GetBuffer(MAX_PATH);
      //  set the number of filters
      dlgFile.m_ofn.nMaxCustFilter = nNumFilters;
      //  set the default filter.
      dlgFile.m_ofn.nFilterIndex = 0;

      //  show the dialog.
      if (dlgFile.DoModal()==IDOK)
      {
        //  release the buffer used for the filename.
        szSelFilename.ReleaseBuffer();

        FILE *fPlot;
        if ((fPlot = fopen(szSelFilename, "w"))!=NULL)
        {
          int nErr = 0;
          for (UINT ii=0; ii<uiPointCount; ii++)
          {
            nErr = fprintf(fPlot, "%f\t%f\n",pptData[ii].x, pptData[ii].y);
          }
          fclose(fPlot);
        }
      }
    }
  }	
}
/////////////////////////////////////////////////////////////////////////////